"""
忘记密码服务
使用图形验证码验证用户身份，通过邮箱重置密码
"""
import logging
from datetime import datetime, timedelta
from typing import Optional
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select
from ..models.user import User
from ..core.auth import get_password_hash
from fastapi import HTTPException

logger = logging.getLogger(__name__)


class ForgotPasswordService:
    """忘记密码服务类"""
    
    def __init__(self, db: AsyncSession):
        self.db = db
    
    async def reset_password_by_email(
        self, 
        email: str, 
        captcha: str, 
        new_password: str,
        session_captcha: str
    ) -> bool:
        """
        通过邮箱和图形验证码重置密码
        
        Args:
            email: 用户邮箱
            captcha: 用户输入的图形验证码
            new_password: 新密码
            session_captcha: 会话中存储的验证码
            
        Returns:
            bool: 重置是否成功
            
        Raises:
            HTTPException: HTTP异常
        """
        try:
            # 1. 验证图形验证码
            if not self._verify_captcha(captcha, session_captcha):
                raise HTTPException(status_code=400, detail="验证码错误，请重新输入")
            
            # 2. 查找用户
            user = await self._find_user_by_email(email)
            if not user:
                raise HTTPException(status_code=404, detail="该邮箱未注册")
            
            # 3. 检查用户状态
            if not user.is_active:
                raise HTTPException(status_code=403, detail="账户已被禁用，请联系管理员")
            
            # 4. 更新密码
            user.password_hash = get_password_hash(new_password)
            user.updated_at = datetime.utcnow()
            
            await self.db.commit()
            await self.db.refresh(user)
            
            logger.info(f"用户 {email} 通过图形验证码成功重置密码")
            return True
            
        except HTTPException:
            raise
        except Exception as e:
            logger.error(f"重置密码失败: {str(e)}")
            await self.db.rollback()
            raise HTTPException(status_code=500, detail="密码重置失败，请稍后重试")
    
    def _verify_captcha(self, input_captcha: str, session_captcha: str) -> bool:
        """
        验证图形验证码
        
        Args:
            input_captcha: 用户输入的验证码
            session_captcha: 会话中存储的验证码
            
        Returns:
            bool: 验证是否通过
        """
        if not input_captcha or not session_captcha:
            return False
        
        # 不区分大小写比较
        return input_captcha.lower().strip() == session_captcha.lower().strip()
    
    async def _find_user_by_email(self, email: str) -> Optional[User]:
        """
        根据邮箱查找用户
        
        Args:
            email: 用户邮箱
            
        Returns:
            Optional[User]: 用户对象或None
        """
        try:
            result = await self.db.execute(
                select(User).where(User.email == email)
            )
            return result.scalar_one_or_none()
        except Exception as e:
            logger.error(f"查找用户失败: {str(e)}")
            return None
